
; CC8E Version 1.3B, Copyright (c) B Knudsen Data
; C compiler for the PIC18 microcontrollers
; ************  22. Feb 2010   9:59  *************

	processor  PIC18F14K22
	radix  DEC

	__config 0x300001, 0x38
	__config 0x300002, 0x1F
	__config 0x300003, 0x6
	__config 0x300005, 0x0
	__config 0x300006, 0x1
	__config 0x300008, 0x3
	__config 0x300009, 0xC0
	__config 0x30000A, 0x3
	__config 0x30000B, 0xE0
	__config 0x30000C, 0x3
	__config 0x30000D, 0x40

TBLPTR      EQU   0xFF6
TABLAT      EQU   0xFF5
PRODL       EQU   0xFF3
INDF0       EQU   0xFEF
FSR0        EQU   0xFE9
WREG        EQU   0xFE8
BSR         EQU   0xFE0
STATUS      EQU   0xFD8
Carry       EQU   0
Zero_       EQU   2
TMR0L       EQU   0xFD6
T0CON       EQU   0xFD5
OSCCON      EQU   0xFD3
WDTCON      EQU   0xFD1
TMR1H       EQU   0xFCF
T1CON       EQU   0xFCD
TMR2        EQU   0xFCC
PR2         EQU   0xFCB
T2CON       EQU   0xFCA
ADRESH      EQU   0xFC4
ADCON0      EQU   0xFC2
ADCON1      EQU   0xFC1
ADCON2      EQU   0xFC0
CCPR1L      EQU   0xFBE
CCP1CON     EQU   0xFBD
VREFCON0    EQU   0xFBA
PSTRCON     EQU   0xFB9
TMR3H       EQU   0xFB3
TMR3L       EQU   0xFB2
T3CON       EQU   0xFB1
SPBRGH      EQU   0xFB0
SPBRG       EQU   0xFAF
TXREG       EQU   0xFAD
EEADRH      EQU   0xFAA
EEADR       EQU   0xFA9
EEDATA      EQU   0xFA8
EECON2      EQU   0xFA7
TRISC       EQU   0xF94
TRISB       EQU   0xF93
TRISA       EQU   0xF92
LATC        EQU   0xF8B
LATB        EQU   0xF8A
LATA        EQU   0xF89
PORTC       EQU   0xF82
PORTB       EQU   0xF81
PORTA       EQU   0xF80
ANSEL       EQU   0xF7E
IOCB        EQU   0xF7A
IOCA        EQU   0xF79
WPUB        EQU   0xF78
WPUA        EQU   0xF77
TMR0IF      EQU   2
TMR0IE      EQU   5
GIEL        EQU   6
GIE         EQU   7
GIEH        EQU   7
TMR0IP      EQU   2
IPEN        EQU   7
DC1B0       EQU   4
DC1B1       EQU   5
BRG16       EQU   3
BRGH        EQU   2
SYNC        EQU   4
TXEN        EQU   5
SPEN        EQU   7
RD          EQU   0
WR          EQU   1
WREN        EQU   2
CFGS        EQU   6
EEPGD       EQU   7
TMR3IP      EQU   1
TMR3IF      EQU   1
EEIF        EQU   4
TMR3IE      EQU   1
EEIE        EQU   4
TMR1IP      EQU   0
TXIP        EQU   4
RCIP        EQU   5
TMR1IF      EQU   0
TXIF        EQU   4
RCIF        EQU   5
TMR1IE      EQU   0
TMR2IE      EQU   1
TXIE        EQU   4
RCIE        EQU   5
sv_FSR0     EQU   0x00
svrSTATUS   EQU   0x02
svrBSR      EQU   0x03
svrWREG     EQU   0x04
time_second EQU   0x09
count       EQU   0x0A
tick        EQU   0x0B
pwm2_lowTime EQU   0x0C
pwm2_highTime EQU   0x0D
high        EQU   0x07
low         EQU   0x08
inStart     EQU   0x16
inEnd       EQU   0x17
outStart    EQU   0x18
outEnd      EQU   0x19
data        EQU   0x05
countA      EQU   0x1A
countB      EQU   0x1B
filteredData EQU   0x1C
newData     EQU   0x05
delta       EQU   0x06
changes     EQU   0x07
eeWrStart   EQU   0x3D
eeWrEnd     EQU   0x3E
data_2      EQU   0xF7F
bytes       EQU   0xF7F
checksum    EQU   0xF7F
data_3      EQU   0xF7F
bytes_2     EQU   0xF7F
data_4      EQU   0xF7F
bytes_3     EQU   0xF7F
checkByte   EQU   0xF7F
addr        EQU   0xF7F
data_5      EQU   0xF7F
addr_2      EQU   0xF7F
pulseLength EQU   0x07
steering    EQU   0x08
temperature EQU   0x4A
tempRange   EQU   0x4B
oldTempRange EQU   0x05
temperature_2 EQU   0x06
filteredInputs EQU   0x4C
oldInputs   EQU   0x4D
patternSelect EQU   0x4E
high_2      EQU   0x05
low_2       EQU   0x06
needToUpdate EQU   0
ci          EQU   0x07

	GOTO main

  ; FILE main.c
			;#include "hexcodes.h"
			;#include "int18xxx.h"
			;
			;#include "time.h"
			;#include "rtc.h"
			;#include "debounce.h"
			;#include "pwm2.h"
			;#include "io.h"
			;#include "eeprom.h"
			;#include "epwm.h"
			;#include "param.h"
			;#include "irda.h"
			;
			;#define  FREQ  64000000
			;#define  FOSC  16000000
			;
			;// CONFIG Registers
			;
			;#define CONFIG1H config[1]
			;#define CONFIG2L config[2]
			;#define CONFIG2H config[3]
			;#define CONFIG3H config[5]
			;#define CONFIG4L config[6]
			;#define CONFIG5L config[8]
			;#define CONFIG5H config[9]
			;#define CONFIG6L config[10]
			;#define CONFIG6H config[11]
			;#define CONFIG7L config[12]
			;#define CONFIG7H config[13]
			;
			;// Comments state which options are not left at defaut settings
			;#pragma CONFIG1H = 0b00111000    // Internal OSC, PLL enabled Freq=64MHz
			;#pragma CONFIG2L = 0b00011111    // default
			;#pragma CONFIG2H = 0b00000110    // WDT controlled in WDTCON register, 1:8 postscale (32mS)
			;#pragma CONFIG3H = 0b00000000    // MCLR internal, wait for HFINTOSC to stabilize
			;#pragma CONFIG4L = 0b00000001    // Single supply ICSP disabled
			;#pragma CONFIG5L = 0b00000011    // default
			;#pragma CONFIG5H = 0b11000000    // default
			;#pragma CONFIG6L = 0b00000011    // default
			;#pragma CONFIG6H = 0b11100000    // default
			;#pragma CONFIG7L = 0b00000011    // default
			;#pragma CONFIG7H = 0b01000000    // default
			;
			;
			;
			;/* Pin   Pin   Pragma
			;   SOT   DIP   Port  Dir   Name
			;   1     1     Vdd         Power
			;   2     2     RA5   Out   DIR
			;   3     3     AN3   Ana   T_MON
			;   4     4     RA3   In    SEL
			;   5     5     RC5   Out   HB_PWM (P1A)
			;   6     6     RC4   Out   SP_PWM (P1B)
			;   7     7     RC3   Out   HS_PWM (P1C)
			;   8     8     RC6   In    Spare_A
			;   9     9     RC7   In    Spare_B
			;   10    10    RB7   In    RX
			;   11    11    RB6   Out   CLK
			;   12    12    RB5   Out   TX
			;   13    13    RB4   Out   EN
			;   14    14    AN6   Ana   HB_MON
			;   15    15    AN5   Ana   SP_MON
			;   16    16    AN4   Ana   HS_MON
			;   17    17    AN2   Ana   V_MON
			;   18    18    RA1   In    LB
			;   19    19    RA0   In    HB
			;   20    20    Vss         Ground
			;*/
			;
			;
			;/*
			;	Resource allocation:
			;
			;	AtoD: 	Pins AN2, AN3, AN4, AN5, AN6
			;	TimerO:	IrDA clock
			;	Timer1:	OS Tick & Real Time Clock
			;	Timer2:	EPWM
			;	Timer3:	PWM2
			;
			;
			;
			;*/
			;
			;#define HS_pin PORTC.3
			;#define SP_pin PORTC.4
			;#define HB_pin PORTC.5
			;
			;#define HS_tris TRISC.3
			;#define SP_tris TRISC.4
			;#define HB_tris TRISC.5
			;
			;#define PWM2_PIN  HS_pin
			;
			;#define  V_MON_CHAN  2
			;#define  T_MON_CHAN  3
			;#define  HS_MON_CHAN 4
			;#define  SP_MON_CHAN 5
			;#define  HB_MON_CHAN 6
			;
			;#define  V_MON_CONV  0b00001011
			;#define  T_MON_CONV  0b00001111
			;#define  HS_MON_CONV 0b00010011
			;#define  SP_MON_CONV 0b00010111
			;#define  HB_MON_CONV 0b00011011
			;
			;#define	LB_IN_PIN	1
			;#define	HB_IN_PIN	0
			;#define	SEL_IN_PIN	3	
			;
			;#define  DIR_PIN     PORTA.5
			;#define  CLK_PIN     PORTB.6
			;
			;#pragma origin 0x8
	ORG 0x0008
			;interrupt highPriorityServer( void )
			;{
highPriorityServer
			;   isr_pwm2();
	RCALL isr_pwm2
			;   #pragma fastMode
			;}
	RETFIE 1
			;
			;// char tick;
			;
			;#pragma origin 0x18
	ORG 0x0018
			;interrupt lowPriorityServer( void )
			;{
lowPriorityServer
			;   uns16 sv_FSR0;
			;   int_save_registers
			;; #define  int_save_registers  \
			;;    char svrSTATUS, svrBSR, svrWREG;  \
			;;    svrSTATUS = STATUS;  \
	MOVFF STATUS,svrSTATUS
			;;    svrBSR = BSR; \
	MOVFF BSR,svrBSR
			;;    svrWREG = W;
	MOVWF svrWREG,0
			;   sv_FSR0 = FSR0;
	MOVFF FSR0,sv_FSR0
	MOVFF FSR0+1,sv_FSR0+1
			;
			;   if( TMR0IF )	isr_irda();
	BTFSC 0xFF2,TMR0IF,0
	RCALL isr_irda
			;   if( TXIF )		isr_putchar();
	BTFSC 0xF9E,TXIF,0
	RCALL isr_putchar
			;   if( RCIF )		isr_getchar();
	BTFSC 0xF9E,RCIF,0
	RCALL isr_getchar
			;	if( TMR1IF )	isr_time();
	BTFSC 0xF9E,TMR1IF,0
	RCALL isr_time
			;	if( EEIF )		isr_ee_write();
	BTFSC 0xFA1,EEIF,0
	RCALL isr_ee_write
			;
			;   FSR0 = sv_FSR0;
	MOVFF sv_FSR0,FSR0
	MOVFF sv_FSR0+1,FSR0+1
			;   int_restore_registers
			;; #define  int_restore_registers \
			;;    W = svrWREG;  \
	MOVF  svrWREG,W,0
			;;    BSR = svrBSR;  \
	MOVFF svrBSR,BSR
			;;    STATUS = svrSTATUS;
	MOVFF svrSTATUS,STATUS
			;}
	RETFIE
			;
			;
			;/*
			;Temp  Voltage	Count (4.096 ref)	Count (8 bit)
			;-40   4.99		3FF					FF
			;-20   4.96		3FF					FF
			;  0   4.87		3FF					FF
			; 25	4.55		3FF					FF
			; 50	3.82		3BA					EE
			; 75	2.74		2AC					AB
			;100	1.69		1A6					69
			;125	0.96		0EF					3B
			;*/
			;
			;//unsigned long analogData[5];
			;const char analogConv[5] = { V_MON_CONV, T_MON_CONV, HS_MON_CONV, SP_MON_CONV, HB_MON_CONV }; 
			;
			;void configAtoD( void )
			;{
configAtoD
			;   // Channels 2,3,4,5,6 are analog
			;
			;   // set the ANS bits HI for AtoD inputs, LO for digital
			;   ANSEL = 0b01111100;
	MOVLW 124
	MOVWF ANSEL,0
			;   
			;   // set TRIS bits HI for AtoD inputs
			;   TRISA.2 = 1;   // AN2 = RA2
	BSF   TRISA,2,0
			;   TRISA.4 = 1;   // AN3 = RA4
	BSF   TRISA,4,0
			;   TRISC.0 = 1;   // AN4 = RC0
	BSF   TRISC,0,0
			;   TRISC.1 = 1;   // AN5 = RC1
	BSF   TRISC,1,0
			;   TRISC.2 = 1;   // AN6 = RC2
	BSF   TRISC,2,0
			;
			;   // set voltage ref to FVR - GND
			;   ADCON1 = 0b00001000;
	MOVLW 8
	MOVWF ADCON1,0
			;
			;   // enable FVR x 4
			;   // Therefore 4mV / count
			;   VREFCON0 = 0b10110000;
	MOVLW 176
	MOVWF VREFCON0,0
			;   
			;   // Left justified, acq = 8Tad, Fosc = Tosc/8 = 2uS
			;   ADCON2 = 0b00100001;
	MOVLW 33
	MOVWF ADCON2,0
			;}
	RETURN

  ; FILE time.c
			;// Time Routines
			;
			;#ifndef _TIME_C_
			;#define _TIME_C_
			;
			;// RTC is run on Timer1
			;// set to one tick per second
			;// Assumes 16MHz clock
			;//   Fosc = 4MHz
			;//   Low byte of timer divides by 256 giving 15625 counts per second into High byte
			;//   High byte divides by 125, giving 125 counts per second (125*125 = 15625)
			;//   To get counter to divide by 125 preload High byte with 256-125 = 131
			;//   OS tick is generated on rollover = 15625/125 = 125Hz = 8mS
			;
			;// T1CON
			;// 0bWRWW WWWW
			;//   |||| |||+-- 1=Enable Timer1, 0=Disable
			;//   |||| ||+--- 1=External clock, 0=Internal (Fosc)
			;//   |||| |+---- 1=No external sync, 0=External sync (ignored for Fosc)
			;//   |||| +----- 1=TMR1 osc enabled, 0=Disabled
			;//   ||++------- Prescaler: 11=1:8, 10=1:4, 01=1:2, 00=1:1 
			;//   |+--------- Main system clock source 
			;//   +---------- 1=16 bit operation, 0=8 bit operation
			;
			;#define TMR1_PRELOAD		131
			;#define TMR1_SECOND		124
			;
			;char time_second;
			;char count;
			;char tick;
			;
			;void time_config( void )
			;{
time_config
			;	T1CON = 0b00100001;
	MOVLW 33
	MOVWF T1CON,0
			;	TMR1IP = 0;	// low priority interrupt
	BCF   0xF9F,TMR1IP,0
			;	TMR1H = TMR1_PRELOAD;
	MOVLW 131
	MOVWF TMR1H,0
			;} 
	RETURN
			;
			;// we should get here within 256 instructions of the interrupt
			;// so we can assume we have time to modify the high byte preload
			;// without causing a glitch should the low byte value roll over
			;void isr_time( void )
			;{
isr_time
			;   tick++;
	INCF  tick,1,0
			;	TMR1IF = 0;
	BCF   0xF9E,TMR1IF,0
			;	TMR1H = TMR1_PRELOAD;
	MOVLW 131
	MOVWF TMR1H,0
			;	
			;	if( ++count >= TMR1_SECOND )
	INCF  count,1,0
	MOVLW 123
	CPFSGT count,0
	BRA   m001
			;	{
			;		time_second++;
	INCF  time_second,1,0
			;		count = 0;
	CLRF  count,0
			;	}		
			;}
m001	RETURN

  ; FILE pwm2.c
			;#ifndef _pwm2_c
			;#define _pwm2_c
			;
			;// Secondary PWM based on TMR3
			;
			;// T3CON
			;// 0bW0WW WWWW
			;//   | || |||+-- TMR3ON: 1=Enable, 0=Disable
			;//   | || ||+--- TMR3CS: 1=external source, 0=Fosc
			;//   | || |+---- T3SYNC: 1=Don't sync external clock, 0=Sync
			;//   | || +----- T3CCP1: 1=TMR3 is source for CCP, 0=TMR1 is source
			;//   | ++------- T3CKPS: 11=1:8, 10=1:4, 01=1:2, 00=1:1 
			;//   +---------- RD16: 1=16 bit r/w, 0=8 bit
			;
			;#if FOSC == 4000000
			;#define T3CON_INIT	0b00001001	// Timer ON, 1:1
			;#elif FOSC == 16000000
			;#define T3CON_INIT	0b00001001	// Timer ON, 1:1
			;#else
			;#error pwm2.c: There is no value for T3CON at the specified clock speed
			;#endif 
			;
			;char pwm2_lowTime, pwm2_highTime;
			;
			;
			;void pwm2_config( void )
			;{
pwm2_config
			;   T3CON = T3CON_INIT;
	MOVLW 9
	MOVWF T3CON,0
			;   TMR3IP = 1;    // High priority interrupt
	BSF   0xFA2,TMR3IP,0
			;}
	RETURN
			;
			;void pwm2_set( char high, char low )
			;{
pwm2_set
	MOVWF low,0
			;   pwm2_highTime = high;
	MOVFF high,pwm2_highTime
			;   pwm2_lowTime = low;
	MOVFF low,pwm2_lowTime
			;} 
	RETURN
			;
			;void pwm2_stop( void )
			;{
pwm2_stop
			;   TMR3IE = 0;
	BCF   0xFA0,TMR3IE,0
			;   PWM2_PIN = 0;
	BCF   PORTC,3,0
			;}
	RETURN
			;
			;void pwm2_start( void )
			;{
pwm2_start
			;   TMR3H = 0xff;
	SETF  TMR3H,0
			;   TMR3L = 0xe0;
	MOVLW 224
	MOVWF TMR3L,0
			;   TMR3IE = 1;
	BSF   0xFA0,TMR3IE,0
			;}
	RETURN
			;
			;void isr_pwm2( void )
			;{
isr_pwm2
			;   if( PWM2_PIN )
	BTFSS PORTC,3,0
	BRA   m002
			;   {
			;      TMR3L += pwm2_lowTime;
	MOVF  pwm2_lowTime,W,0
	ADDWF TMR3L,1,0
			;      PWM2_PIN = 0;
	BCF   PORTC,3,0
			;   }
			;   else
	BRA   m003
			;   {
			;      TMR3L += pwm2_highTime;
m002	MOVF  pwm2_highTime,W,0
	ADDWF TMR3L,1,0
			;      PWM2_PIN = 1;
	BSF   PORTC,3,0
			;   }
			;
			;   TMR3H = 0xff;
m003	SETF  TMR3H,0
			;   TMR3IF = 0;
	BCF   0xFA1,TMR3IF,0
			;}
	RETURN

  ; FILE io.c
			;#ifndef _IO_C
			;#define _IO_C
			;
			;#define IN_BUFFER_SIZE     8
			;#define OUT_BUFFER_SIZE    8
			;
			;char inBuffer[IN_BUFFER_SIZE];
			;//char outBuffer[OUT_BUFFER_SIZE];
			;
			;char inStart, inEnd, outStart, outEnd;
			;//char inStart, inEnd, inSize, outStart, outEnd, outSize;
			;
			;void io_config( void )
			;{
io_config
			;#if FOSC == 4000000
			;   BRG16 = 0;
			;   SYNC = 0;
			;   BRGH = 1;
			;   SPBRGH = 0;
			;   SPBRG = 25;
			;#elif FOSC == 16000000
			;   BRG16 = 0;
	BCF   0xFB8,BRG16,0
			;   SYNC = 0;
	BCF   0xFAC,SYNC,0
			;   BRGH = 0;
	BCF   0xFAC,BRGH,0
			;   SPBRGH = 0;
	CLRF  SPBRGH,0
			;   SPBRG = 25;
	MOVLW 25
	MOVWF SPBRG,0
			;#else
			;#error There is no baud rate setting for the chosen Fosc speed.
			;#endif
			;
			;   SPEN = 1;   // Enable serial port
	BSF   0xFAB,SPEN,0
			;   TXEN = 1;   // Enable transmit
	BSF   0xFAC,TXEN,0
			;
			;   RCIP = 0;   // Rx is low priority
	BCF   0xF9F,RCIP,0
			;   TXIP = 0;   // Tx is low priority
	BCF   0xF9F,TXIP,0
			;
			;   RCIE = 0;   // Rx buffer is empty
	BCF   0xF9D,RCIE,0
			;   TXIE = 0;   // Tx buffer is empty
	BCF   0xF9D,TXIE,0
			;
			;   inStart = 0;
	CLRF  inStart,0
			;   inEnd = 0;
	CLRF  inEnd,0
			;   outStart = 0;
	CLRF  outStart,0
			;   outEnd = 0;
	CLRF  outEnd,0
			;}
	RETURN
			;
			;char putchar( char data )
			;{
putchar
	MOVWF data,0
			;   // Check to see if buffer is full.
			;   // Indicated by start=end AND interrupt already enabled
			;   if( (inStart==inEnd) && (TXIE==1) )
	MOVF  inStart,W,0
	CPFSEQ inEnd,0
	BRA   m004
	BTFSC 0xF9D,TXIE,0
			;      return( 1 );
	RETLW 1
			;   
			;   inBuffer[inStart] = data;
m004	CLRF  FSR0+1,0
	MOVLW 14
	ADDWF inStart,W,0
	MOVWF FSR0,0
	MOVFF data,INDF0
			;   inStart++;
	INCF  inStart,1,0
			;   if( inStart >= IN_BUFFER_SIZE )
	MOVLW 8
	CPFSLT inStart,0
			;      inStart = 0;
	CLRF  inStart,0
			;
			;   TXIE = 1;
	BSF   0xF9D,TXIE,0
			;   return( 0 );
	RETLW 0
			;}
			;
			;void isr_putchar( void )
			;{
isr_putchar
			;   if( !TXIE )
	BTFSS 0xF9D,TXIE,0
			;      return;
	RETURN
			;
			;   TXREG = inBuffer[inEnd];
	CLRF  FSR0+1,0
	MOVLW 14
	ADDWF inEnd,W,0
	MOVWF FSR0,0
	MOVFF INDF0,TXREG
			;   inEnd++;
	INCF  inEnd,1,0
			;   if( inEnd >= IN_BUFFER_SIZE )
	MOVLW 8
	CPFSLT inEnd,0
			;      inEnd = 0;
	CLRF  inEnd,0
			;
			;   // disable interrupt if buffer is empty.
			;   if( inEnd == inStart )
	MOVF  inEnd,W,0
	CPFSEQ inStart,0
	BRA   m005
			;      TXIE = 0;
	BCF   0xF9D,TXIE,0
			;}
m005	RETURN
			;
			;void isr_getchar( void )
			;{
isr_getchar
			;}
	RETURN

  ; FILE debounce.c
			;#ifndef _DEBOUNCE_C_
			;#define _DEBOUNCE_C_
			;
			;#include "debounce.h"
			;
			;char countA, countB, filteredData;
			;
			;void initDebounce( void )
			;{
initDebounce
			;   countA = 0;
	CLRF  countA,0
			;   countB = 0;
	CLRF  countB,0
			;   filteredData = 0;
	CLRF  filteredData,0
			;}
	RETURN
			;
			;char debounce( char newData )
			;{
debounce
	MOVWF newData,0
			;	char delta, changes;
			;
			;   delta = newData ^ filteredData;	// find all the changed bits
	MOVF  filteredData,W,0
	XORWF newData,W,0
	MOVWF delta,0
			;
			;   countA ^= countB;						// increment the counters
	MOVF  countB,W,0
	XORWF countA,1,0
			;   countB = ~countB;						//
	COMF  countB,1,0
			;
			;   countA &= delta;						// reset the counters if no changes
	MOVF  delta,W,0
	ANDWF countA,1,0
			;   countB &= delta;						//   were detected
	MOVF  delta,W,0
	ANDWF countB,1,0
			;
			;   changes = ~( ~delta | countA | countB );
	COMF  delta,W,0
	IORWF countA,W,0
	IORWF countB,W,0
	XORLW 255
	MOVWF changes,0
			;   filteredData ^= changes;
	MOVF  changes,W,0
	XORWF filteredData,1,0
			;
			;	return filteredData;
	MOVF  filteredData,W,0
	RETURN

  ; FILE eeprom.c
			;// Memory usage
			;// - Accumulated time values are stored in 24 bit numbers
			;// - the value is incremented every accumulated minute
			;// - each value is duplicated and stored with an 8 bit checksum
			;// - on startup the numbers are validated by reading them
			;// - an erroneous value is restored by copying from its twin
			;// - this means a single 24 bit value actually requires 8 bytes
			;
			;// EECON1
			;// 0bWW0W WWSS
			;//   || | |||+-- RD: 1=Initiate Read
			;//   || | ||+--- WR: 1=Initiate Write, 0=Write complete
			;//   || | |+---- WREN: 1=Write Enable, 0=Write Disable
			;//   || | +----- WRERR: 1=Write Error, 0=Write OK
			;//   || +------- FREE: 1=Erase block, 0=Write 
			;//   |+--------- CFGS: 1=Access config block, 0=Acccess Data block
			;//   +---------- EEPGD: 1=Access Flash program, 0=Access EEPROM data
			;
			;#define RUN_TIME		0
			;#define LB_LP_TIME	1
			;
			;#define EE_WRITE_BUFFER_SIZE  16
			;#define EE_WRITE_BUFFER_MASK  0x0f
			;
			;char eeWrData[EE_WRITE_BUFFER_SIZE];
			;char eeWrAddr[EE_WRITE_BUFFER_SIZE];
			;char eeWrStart, eeWrEnd;
			;
			;char *ee_data;
			;char ee_count;
			;
			;char chk_sum( char *data, char bytes )
			;{
chk_sum
	MOVWF bytes,0
			;   char checksum = *data++;
	MOVFF data_2,FSR0
	CLRF  FSR0+1,0
	MOVFF INDF0,checksum
	INCF  data_2,1,0
			;   
			;   while( --bytes )
m006	DECF  bytes,1,0
	MOVF  bytes,W,0
	BTFSC 0xFD8,Zero_,0
	BRA   m007
			;      checksum += *data++;
	MOVFF data_2,FSR0
	CLRF  FSR0+1,0
	MOVF  INDF0,W,0
	ADDWF checksum,1,0
	INCF  data_2,1,0
	BRA   m006
			;
			;   return( checksum );
m007	MOVF  checksum,W,0
	RETURN
			;}
			;
			;char chk_generate( char *data, char bytes )
			;{
chk_generate
	MOVWF bytes_2,0
			;   W = chk_sum( data, bytes );
	MOVFF data_3,data_2
	MOVF  bytes_2,W,0
	RCALL chk_sum
			;   return( negate(W) );
	NEGF  WREG,W,0
	RETURN
			;}
			;
			;char chk_compare( char *data, char bytes, char checkByte )
			;{
chk_compare
	MOVWF checkByte,0
			;   return( checkByte + chk_sum( data, bytes ) );
	MOVFF data_4,data_2
	MOVF  bytes_3,W,0
	RCALL chk_sum
	ADDWF checkByte,W,0
	RETURN
			;}
			;
			;char ee_getchar( char addr )
			;{
ee_getchar
	MOVWF addr,0
			;	EEPGD = 0;
	BCF   0xFA6,EEPGD,0
			;	CFGS = 0;
	BCF   0xFA6,CFGS,0
			;	EEADR = addr;
	MOVFF addr,EEADR
			;   RD = 1;
	BSF   0xFA6,RD,0
			;   return( EEDATA );
	MOVF  EEDATA,W,0
	RETURN
			;}
			;
			;char ee_putchar( char data, char addr )
			;{
ee_putchar
	MOVWF addr_2,0
			;   // Check to see if buffer is full.
			;   // Indicated by start=end AND interrupt already enabled
			;   if( (eeWrStart == eeWrEnd) && (EEIE==1) )
	MOVF  eeWrStart,W,0
	CPFSEQ eeWrEnd,0
	BRA   m008
	BTFSC 0xFA0,EEIE,0
			;      return 1;
	RETLW 1
			;
			;   eeWrData[eeWrStart] = data;
m008	CLRF  FSR0+1,0
	MOVLW 29
	ADDWF eeWrStart,W,0
	MOVWF FSR0,0
	MOVFF data_5,INDF0
			;   eeWrAddr[eeWrStart] = addr;
	CLRF  FSR0+1,0
	MOVLW 45
	ADDWF eeWrStart,W,0
	MOVWF FSR0,0
	MOVFF addr_2,INDF0
			;
			;   eeWrStart = ++eeWrStart & EE_WRITE_BUFFER_MASK;
	INCF  eeWrStart,1,0
	MOVLW 15
	ANDWF eeWrStart,1,0
			;   
			;   if( EEIE == 0 )
	BTFSC 0xFA0,EEIE,0
	BRA   m009
			;   {
			;      EEIE = 1;
	BSF   0xFA0,EEIE,0
			;      ee_writeByte();
	RCALL ee_writeByte
			;   }
			;   return( 0 );
m009	RETLW 0
			;}
			;
			;// Check to see if write buffer is empty
			;// Indicated by interrupt disabled
			;// beacuse interrupt is enabled when something is in buffer
			;char ee_writeEmpty( void )
			;{
ee_writeEmpty
			;   if( EEIE==0 ) 
	BTFSS 0xFA0,EEIE,0
			;      return( 1 );
	RETLW 1
			;   return( 0 );
	RETLW 0
			;}
			;
			;void isr_ee_write( void )
			;{
isr_ee_write
			;	EEIF = 0;
	BCF   0xFA1,EEIF,0
			;	WREN = 0;
	BCF   0xFA6,WREN,0
			;
			;   if( eeWrStart == eeWrEnd )
	MOVF  eeWrStart,W,0
	CPFSEQ eeWrEnd,0
	BRA   ee_writeByte
			;      EEIE = 0;
	BCF   0xFA0,EEIE,0
			;   else
			;      ee_writeByte();
			;}
m010	RETURN
			;
			;void ee_writeByte( void )
			;{
ee_writeByte
			;   EEDATA = eeWrData[eeWrEnd];
	CLRF  FSR0+1,0
	MOVLW 29
	ADDWF eeWrEnd,W,0
	MOVWF FSR0,0
	MOVFF INDF0,EEDATA
			;   EEADR = eeWrAddr[eeWrEnd];
	CLRF  FSR0+1,0
	MOVLW 45
	ADDWF eeWrEnd,W,0
	MOVWF FSR0,0
	MOVFF INDF0,EEADR
			;	EEADRH = 0;
	CLRF  EEADRH,0
			;	EEPGD = 0;
	BCF   0xFA6,EEPGD,0
			;	CFGS = 0;
	BCF   0xFA6,CFGS,0
			;	WREN = 1;
	BSF   0xFA6,WREN,0
			;
			;	GIE = 0;
	BCF   0xFF2,GIE,0
			;	
			;	EECON2 = 0x55;
	MOVLW 85
	MOVWF EECON2,0
			;	EECON2 = 0xaa;
	MOVLW 170
	MOVWF EECON2,0
			;	WR = 1;
	BSF   0xFA6,WR,0
			;
			;	GIE = 1;
	BSF   0xFF2,GIE,0
			;
			;   eeWrEnd = ++eeWrEnd & EE_WRITE_BUFFER_MASK;
	INCF  eeWrEnd,1,0
	MOVLW 15
	ANDWF eeWrEnd,1,0
			;}
	RETURN

  ; FILE epwm.c
			;#ifndef _epwm_c
			;#define _epwm_c
			;
			;// Period is 320 counts = 50KHz
			;// 320/4 = 80
			;
			;#define PR2_INIT	80
			;
			;#if FOSC == 4000000
			;#define T2CON_INIT	0b00000100		// Timer ON, 1:1
			;#elif FOSC == 16000000
			;#define T2CON_INIT	0b00000101		// Timer ON, 1:4
			;#else
			;#error epwm.c: There is no value for T2CON at the specified clock speed
			;#endif 
			;
			;void epwm_config( void )
			;{
epwm_config
			;   CCP1CON = 0b00001100;
	MOVLW 12
	MOVWF CCP1CON,0
			;   T2CON = T2CON_INIT;
	MOVLW 5
	MOVWF T2CON,0
			;   TMR2 = 0;
	CLRF  TMR2,0
			;   PR2 = PR2_INIT;
	MOVLW 80
	MOVWF PR2,0
			;   epwm_set( 0, 0 );
	CLRF  pulseLength,0
	MOVLW 0
	BRA   epwm_set
			;}
			;
			;void epwm_set( char pulseLength, char steering )
			;{
epwm_set
	MOVWF steering,0
			;   DC1B0 = pulseLength.0;
	BTFSS pulseLength,0,0
	BCF   0xFBD,DC1B0,0
	BTFSC pulseLength,0,0
	BSF   0xFBD,DC1B0,0
			;   DC1B1 = pulseLength.1;
	BTFSS pulseLength,1,0
	BCF   0xFBD,DC1B1,0
	BTFSC pulseLength,1,0
	BSF   0xFBD,DC1B1,0
			;   CCPR1L = pulseLength >> 2;
	BCF   0xFD8,Carry,0
	RRCF  pulseLength,W,0
	MOVWF CCPR1L,0
	BCF   0xFD8,Carry,0
	RRCF  CCPR1L,1,0
			;   PSTRCON = steering;
	MOVFF steering,PSTRCON
			;}
	RETURN

  ; FILE irda.c
			;#ifndef _irda_c
			;#define _irda_c
			;
			;// Generate a 153600 Hz signal
			;// Count to 52 pulses at 16MHz, toggle clock pin
			;// Note - inhibited for 2 clock cycles when value is updated
			;
			;#define TMR0_PRELOAD_LO    207
			;#define TMR0_PRELOAD_HI    207
			;
			;void irda_config( void )
			;{
irda_config
			;   TMR0L = TMR0_PRELOAD_LO;
	MOVLW 207
	MOVWF TMR0L,0
			;   T0CON = 0b11001000;
	MOVLW 200
	MOVWF T0CON,0
			;   TMR0IP = 0;    // low priority
	BCF   0xFF1,TMR0IP,0
			;}
	RETURN
			;
			;void isr_irda( void )
			;{
isr_irda
			;   if( CLK_PIN )
	BTFSS PORTB,6,0
	BRA   m011
			;   {
			;      TMR0L += TMR0_PRELOAD_LO; 
	MOVLW 207
	ADDWF TMR0L,1,0
			;      CLK_PIN = 0;
	BCF   PORTB,6,0
			;   }
			;   else
	BRA   m012
			;   {  
			;      TMR0L += TMR0_PRELOAD_HI; 
m011	MOVLW 207
	ADDWF TMR0L,1,0
			;      CLK_PIN = 1;
	BSF   PORTB,6,0
			;   }
			;   TMR0IF = 0;
m012	BCF   0xFF2,TMR0IF,0
			;}
	RETURN

  ; FILE main.c
			;
			;#include "time.c"
			;//#include "rtc.c"
			;#include "pwm2.c"
			;#include "io.c"
			;#include "debounce.c"
			;#include "eeprom.c"
			;#include "epwm.c"
			;//#include "param.c"
			;#include "irda.c"
			;
			;//unsigned long voltage, temperature;
			;unsigned long voltage;
			;unsigned long hs_current, sp_current, hb_current;
			;static char channel;
			;
			;#if 0
			;void int_atod( void )
			;{
			;   switch( channel )
			;   {
			;      case( 0 ):
			;         voltage = ( (unsigned long)ADRESH<<8 ) | ADRESL;
			;         ADCON0 = T_MON_CONV;
			;         channel = 1;
			;         break;
			;
			;      case( 1 ):
			;         temperature = ( (unsigned long)ADRESH<<8 ) | ADRESL;
			;         ADCON0 = HS_MON_CONV;
			;         channel = 2;
			;         break;
			;
			;      case( 2 ):
			;         hs_current = ( (unsigned long)ADRESH<<8 ) | ADRESL;
			;         ADCON0 = SP_MON_CONV;
			;         channel = 3;
			;         break;
			;
			;      case( 3 ):
			;         sp_current = ( (unsigned long)ADRESH<<8 ) | ADRESL;
			;         ADCON0 = HB_MON_CONV;
			;         channel = 4;
			;         break;
			;
			;      case( 4 ):
			;         hb_current = ( (unsigned long)ADRESH<<8 ) | ADRESL;
			;
			;      default:
			;         ADCON0 = V_MON_CONV;
			;         channel = 0;
			;   }
			;}
			;#endif
			;
			;#if 0
			;void int_atod_2( void )
			;{
			;	unsigned long oldVal, newVal, accum;
			;
			;	oldVal = analogData[channel];
			;	newVal = ( (unsigned long)ADRESH<<8 ) | ADRESL;
			;
			;	oldVal >>= 1;
			;	accum = oldVal;
			;
			;	oldVal >>= 1;
			;	accum += oldVal;
			;
			;	oldVal >>= 1;
			;	accum += oldVal;
			;
			;	newVal >>= 3;
			;	accum += newVal;
			;
			;   analogData[channel] = accum;
			;
			;	channel++;
			;	if( channel > 4 )
			;		channel = 0;
			;
			;	ADCON0 = analogConv[channel];
			;}   
			;#endif
			;
			;uns8  temperature;
			;
			;void getTemp( void )
			;{
getTemp
			;   // Filter: NewTmp = (OldTemp + NewTemp )/2
			;	temperature += ADRESH;					// Carry flag is set maintaining a 9 bit result
	MOVF  ADRESH,W,0
	ADDWF temperature,1,0
			;	temperature = rr( temperature );		// rotate right through carry;
	RRCF  temperature,1,0
			;   ADCON0 = T_MON_CONV;						// Initiate next conversion
	MOVLW 15
	MOVWF ADCON0,0
			;}
	RETURN
			;
			;// Temperature compensation
			;// Note: Lower temperatures have higher acquired values
			;// Lo		Hi 	Ratio
			;//	<85	85		100%
			;// 85		90		90%
			;//	90		95		75%
			;//	95		>95	50%
			;
			;#define TEMP_MINIMUM		143		// equal to 85'C
			;#define TEMP_MIDDLE		117		// equal to 95'C
			;#define TEMP_MAXIMUM		94			// equal to 105'C
			;
			;enum { TEMP_COOL, TEMP_WARM, TEMP_HOT, TEMP_EXTREME, TEMP_MAX };
			;
			;char tempRange;
			;
			;char updateTempRange( void );
			;char setTempRange( char temperature );
			;
			;char updateTempRange( void )
			;{
updateTempRange
			;	char oldTempRange = tempRange;
	MOVFF tempRange,oldTempRange
			;	tempRange = setTempRange( temperature );
	MOVF  temperature,W,0
	RCALL setTempRange
	MOVWF tempRange,0
			;	return( oldTempRange ^ tempRange );
	MOVF  tempRange,W,0
	XORWF oldTempRange,W,0
	RETURN
			;}
			;
			;char setTempRange( char temperature )
			;{
setTempRange
	MOVWF temperature_2,0
			;	if( temperature > TEMP_MINIMUM )	return TEMP_COOL;
	MOVLW 144
	CPFSLT temperature_2,0
	RETLW 0
			;	if( temperature > TEMP_MIDDLE )	return TEMP_WARM;
	MOVLW 118
	CPFSLT temperature_2,0
	RETLW 1
			;	if( temperature > TEMP_MAXIMUM )	return TEMP_HOT;
	MOVLW 95
	CPFSLT temperature_2,0
	RETLW 2
			;	return TEMP_EXTREME;
	RETLW 3
			;}
			;
			;char filteredInputs, oldInputs;
			;
			;// lbIn is HI when Low Beam should be on
			;// hbIn is HI when High Beam should be on
			;// selIn is HI when Regular Low Beam should be on, LO when 18W Low Beam should be on
			;
			;// LED Currents
			;//
			;// NOMINAL: 1.25V Reference
			;// HotSpot = 606mA   (0.33R current set resistor)
			;// Spread  = 606mA   (0.33R current set resistor)
			;// HiBeam  = 606mA   (0.33R current set resistor)
			;//
			;// Maximum: 2.50 Reference
			;// All = 1212mA
			;//
			;// DRIVE
			;// Hardware will drive at nominal if micro control pins are high impedance
			;//   this is fail-safe (or failed!) mode
			;// Hardware also drives at nominal if reference voltage is at 1.25V, 
			;//   or modulated such that the average is 1.25V
			;// The maximum allowable is 200% over driven, or average input of 2.50V,
			;//   or modulated such that the average is 2.50V
			;// The hardware is set so the that modulation voltage is 5.0V.
			;//   Therefore 25% duty cycle is nominal voltage, 50% duty cycle is double nominal voltage.
			;// The minimum allowable is 0.2V, or about 4% modulation.
			;//   Therefore the minimum modulation is set at 5%.
			;// 0% duty cycle will shut the driver off.
			;//
			;// current = 606 * PWM/64     ->    PWM = current * 64 / 606
			;
			;// Correction factor = 1.16
			;// Current     Current	Vref     DutyCycle	320	256-  320	256-    
			;// Req'd       Adjust				(from Xl)	cnt	inv	rem	inv
			;//	0mA			0			0			0%           
			;//	750mA			871		1.80     31.4%			101	155	219	37
			;//	825mA		   958		1.98     33.5%			107	149	213	43
			;//	850mA		   987		2.04     34.2%			110	146	210	46
			;//	1200mA	   1394		2.87     44.1%			141	115	179	77
			;
			;#define CURR_PERIOD		320	// Note that any PWM2 times MUST be less than 256 counts!!
			;
			;//#define EPWM_0_MA			0
			;//#define EPWM_750_MA     107
			;//#define EPWM_825_MA     124
			;//#define EPWM_850_MA     129
			;//#define EPWM_1000_MA    162
			;//#define EPWM_1100_MA    184
			;//#define EPWM_1200_MA    206
			;
			;enum { EPWM_0, EPWM_750, EPWM_825, EPWM_850, EPWM_1000, EPWM_1100, EPWM_1200, EPWM_MAX };
			;
			;// Current entries in the structure are in the following sequence:
			;// 0ma, 750ma, 825ma, 850ma, 1000ma, 1100ma, 1200ma
			;// Temperature index goes from coolest to warmest
			;const struct { char current[EPWM_MAX]; } currentTable[TEMP_MAX] =
			;{
			;	{ 0, 112, 129, 135, 169, 191, 214 },
			;	{ 0,  96, 111, 116, 146, 166, 187 },
			;	{ 0,  70,  83,  87, 112, 129, 146 },
			;	{ 0,  28,  36,  39,  56,  67,  79 }
			;};	
			;
			;const struct { char high; char low; } pwm2Table[TEMP_MAX] =
			;{
			;	{ 121, 71 },
			;	{ 140, 52 },
			;	{ 169, 23 },
			;	{ 236, 116}		// This one has a 160 count period as opposed to 320
			;};
			;
			;//#define PWM2_750_MA     149
			;//#define PWM2_825_MA     132
			;//#define PWM2_850_MA     127
			;
			;//#define REST_750_MA		43
			;//#define REST_825_MA		60
			;//#define REST_850_MA		65
			;
			;#define OFF_PATTERN     0
			;#define LB_LP_PATTERN   1
			;#define HB_LP_PATTERN   2
			;#define LB_HP_PATTERN   3
			;#define HB_HP_PATTERN   4
			;
			;#define MAX_PATTERN     5
			;
			;// Pulse steering mode values
			;#define PSM_NONE  0b00000000  // All off
			;#define PSM_HS    0b00010100  // HotSpot under EPWM control
			;#define PSM_SP    0b00010010  // Spread under EPWM control
			;#define PSM_LB    0b00010110  // HotSpot and Spread under EPWM control
			;#define PSM_HB    0b00010001
			;#define PSM_HS_HB 0b00010101
			;#define PSM_SP_HB 0b00010011
			;#define PSM_ALL   0b00010111
			;
			;
			;char patternSelect;
			;
			;void setPattern( void )
			;{
setPattern
			;	char high, low;
			;   switch( filteredInputs & 0b00001011 )
	MOVLW 11
	ANDWF filteredInputs,W,0
	XORLW 2
	BTFSC 0xFD8,Zero_,0
	BRA   m013
	XORLW 3
	BTFSC 0xFD8,Zero_,0
	BRA   m014
	XORLW 2
	BTFSC 0xFD8,Zero_,0
	BRA   m014
	XORLW 9
	BTFSC 0xFD8,Zero_,0
	BRA   m015
	XORLW 3
	BTFSC 0xFD8,Zero_,0
	BRA   m016
	XORLW 2
	BTFSC 0xFD8,Zero_,0
	BRA   m016
	BRA   m017
			;   {
			;      case 0b00000010:
			;         patternSelect = LB_LP_PATTERN;
m013	MOVLW 1
	MOVWF patternSelect,0
			;         high = pwm2Table[tempRange].high;
	BCF   0xFD8,Carry,0
	RLCF  tempRange,W,0
	ADDLW 28
	RCALL _const1
	MOVWF high_2,0
			;         low = pwm2Table[tempRange].low;
	BCF   0xFD8,Carry,0
	RLCF  tempRange,W,0
	ADDLW 29
	RCALL _const1
	MOVWF low_2,0
			;         pwm2_set( high, low );
	MOVFF high_2,high
	MOVF  low_2,W,0
	RCALL pwm2_set
			;         pwm2_start();
	RCALL pwm2_start
			;			epwm_set( currentTable[tempRange].current[EPWM_750], PSM_SP );
	MOVLW 7
	MULWF tempRange,0
	MOVF  PRODL,W,0
	ADDLW 1
	RCALL _const1
	MOVWF pulseLength,0
	MOVLW 18
	RCALL epwm_set
			;         break;
	BRA   m018
			;
			;      case 0b00000001:
			;      case 0b00000011:
			;         patternSelect = HB_LP_PATTERN;
m014	MOVLW 2
	MOVWF patternSelect,0
			;         pwm2_stop();
	RCALL pwm2_stop
			;			epwm_set( currentTable[tempRange].current[EPWM_825], PSM_ALL );
	MOVLW 7
	MULWF tempRange,0
	MOVF  PRODL,W,0
	ADDLW 2
	RCALL _const1
	MOVWF pulseLength,0
	MOVLW 23
	RCALL epwm_set
			;         break;
	BRA   m018
			;
			;      case 0b00001010:
			;         patternSelect = LB_HP_PATTERN;
m015	MOVLW 3
	MOVWF patternSelect,0
			;         pwm2_stop();
	RCALL pwm2_stop
			;			epwm_set( currentTable[tempRange].current[EPWM_1200], PSM_LB );
	MOVLW 7
	MULWF tempRange,0
	MOVF  PRODL,W,0
	ADDLW 6
	RCALL _const1
	MOVWF pulseLength,0
	MOVLW 22
	RCALL epwm_set
			;         break;
	BRA   m018
			;
			;      case 0b00001001:
			;      case 0b00001011:
			;         patternSelect = HB_HP_PATTERN;
m016	MOVLW 4
	MOVWF patternSelect,0
			;         pwm2_stop();
	RCALL pwm2_stop
			; 			epwm_set( currentTable[tempRange].current[EPWM_1200], PSM_ALL );
	MOVLW 7
	MULWF tempRange,0
	MOVF  PRODL,W,0
	ADDLW 6
	RCALL _const1
	MOVWF pulseLength,0
	MOVLW 23
	RCALL epwm_set
			;        break;
	BRA   m018
			;
			;      default:
			;         patternSelect = OFF_PATTERN;
m017	CLRF  patternSelect,0
			;         pwm2_stop();
	RCALL pwm2_stop
			;			epwm_set( currentTable[tempRange].current[EPWM_0], PSM_NONE );
	MOVLW 7
	MULWF tempRange,0
	MOVF  PRODL,W,0
	RCALL _const1
	MOVWF pulseLength,0
	MOVLW 0
	BRA   epwm_set
			;   }
			;}
m018	RETURN
			;
			;void configTimer0( void )
			;{
configTimer0
			;   // T0CON
			;   // 0b WWWW WWWW
			;   //    |||| |+++-- T0PS: Prescaler
			;   //    |||| +----- PSA: 1=NO prescaler, 0=Prescaler
			;   //    |||+------- T0SE: 1=Hi to Lo transition, 0=Lo to Hi
			;   //    ||+-------- T0CS: 1=Count on Pin, 0=Count on internal
			;   //    |+--------- T08BIT: 1=8 bit mode, 0=16 bit mode
			;   //    +---------- TMR0ON: 1=Enabled, 0=Disabled
			;   //
			;   // Prescaler
			;   // 000   1:2
			;   // 001   1:4
			;   // 010   1:8
			;   // 011   1:16
			;   // 100   1:32
			;   // 101   1:64
			;   // 110   1:128
			;   // 111   1:256
			;
			;	// T0 runs at 250KHz, so rolls over every 1.024mS 
			;#if FOSC == 4000000
			;#define T0CON_INIT	0b11010011	// Timer ON, 1:16, rolls ov
			;#elif FOSC == 16000000
			;#define T0CON_INIT	0b11010101	// Timer ON, 1:64
			;#else
			;#error main.c: There is no value for T0CON at the specified clock speed
			;#endif 
			;   // Freq = 16MHz, Fosc = 4MHz, Tosc = 250nS
			;	// T0 runs at 250KHz, so rolls over every 1.024mS 
			;   T0CON = T0CON_INIT;
	MOVLW 213
	MOVWF T0CON,0
			;   TMR0IP = 0;    // low priority
	BCF   0xFF1,TMR0IP,0
			;   
			;}
	RETURN
			;
			;
			;bit needToUpdate;
			;
			;void main( void )
			;{
main
			;   // configuration
			;   // setup HI speed internal osc as defined in CONFIG1H
			;   OSCCON = 0b11110000;
	MOVLW 240
	MOVWF OSCCON,0
			;
			;   configAtoD();
	RCALL configAtoD
			;	time_config();
	RCALL time_config
			;   io_config();
	RCALL io_config
			;   pwm2_config();
	RCALL pwm2_config
			;   epwm_config();
	RCALL epwm_config
			;   irda_config();
	RCALL irda_config
			;
			;   PORTA = 0;
	CLRF  PORTA,0
			;   TRISA = 0b00011111;
	MOVLW 31
	MOVWF TRISA,0
			;   LATA = 0;
	CLRF  LATA,0
			;   WPUA = 0;
	CLRF  WPUA,0
			;   IOCA = 0;
	CLRF  IOCA,0
			;   DIR_PIN = 1;   // Set serial direction to Transmit
	BSF   PORTA,5,0
			;
			;   PORTB = 0;
	CLRF  PORTB,0
			;   TRISB = 0b10001111;
	MOVLW 143
	MOVWF TRISB,0
			;   LATB = 0;
	CLRF  LATB,0
			;   WPUB = 0;
	CLRF  WPUB,0
			;   IOCB = 0;
	CLRF  IOCB,0
			;
			;   PORTC = 0;
	CLRF  PORTC,0
			;   TRISC = 0b11111111;
	SETF  TRISC,0
			;   LATC = 0;
	CLRF  LATC,0
			;
			;   // initialization
			;   initDebounce();
	RCALL initDebounce
			;
			;   IPEN = 1;   // Enable prioritized interrupts
	BSF   0xFD0,IPEN,0
			;   TMR0IE = 1; // enable IrDA timer interrupts
	BSF   0xFF2,TMR0IE,0
			;   TMR1IE = 1; // enable OS / RTC imterrupts
	BSF   0xF9D,TMR1IE,0
			;   TMR2IE = 0; // diables EPWM interrupts, not needed
	BCF   0xF9D,TMR2IE,0
			;   TMR3IE = 0; // disable PWM2 timer interrupts until needed
	BCF   0xFA0,TMR3IE,0
			;
			;   GIEH = 1;   // Enable high priority interrupts, in this case TMR3 = PWM2
	BSF   0xFF2,GIEH,0
			;   GIEL = 1;   // Enable low priority interrupts
	BSF   0xFF2,GIEL,0
			;
			;//   debug();
			;
			;// WDT should be updated every iteration of the main loop.
			;// Main loop is 8mS
			;// WDT is set to 1:8, 32mS
			;// Enable WDT
			;   WDTCON = 1;
	MOVLW 1
	MOVWF WDTCON,0
			;
			;   PORTC = 0;
	CLRF  PORTC,0
			;   TRISC = 0b11000111;
	MOVLW 199
	MOVWF TRISC,0
			;
			;   filteredInputs = debounce( PORTA );
	MOVF  PORTA,W,0
	RCALL debounce
	MOVWF filteredInputs,0
			;   oldInputs = filteredInputs;
	MOVFF filteredInputs,oldInputs
			;   patternSelect = OFF_PATTERN;
	CLRF  patternSelect,0
			;   setPattern();
	RCALL setPattern
			;
			;	needToUpdate = 0;
	BCF   0x4F,needToUpdate,0
			;
			;//	initTimers();	// load timers from EEPROM
			;
			;   while( 1 )
			;   {
			;      clrwdt();
m019	CLRWDT
			;      if( tick )
	MOVF  tick,1,0
	BTFSC 0xFD8,Zero_,0
	BRA   m019
			;      {
			;         tick = 0;
	CLRF  tick,0
			;         filteredInputs = debounce( PORTA ); 
	MOVF  PORTA,W,0
	RCALL debounce
	MOVWF filteredInputs,0
			;      
			;         if( oldInputs != filteredInputs )
	MOVF  oldInputs,W,0
	XORWF filteredInputs,W,0
	BTFSC 0xFD8,Zero_,0
	BRA   m020
			;         {
			;            oldInputs = filteredInputs; 
	MOVFF filteredInputs,oldInputs
			;	         needToUpdate = 1;
	BSF   0x4F,needToUpdate,0
			;         }
			;
			;			if( updateTempRange() )
m020	RCALL updateTempRange
	XORLW 0
	BTFSS 0xFD8,Zero_,0
			;				needToUpdate = 1;
	BSF   0x4F,needToUpdate,0
			;
			;			if( needToUpdate )
	BTFSS 0x4F,needToUpdate,0
	BRA   m021
			;			{
			;            setPattern();
	RCALL setPattern
			;            needToUpdate = 0;
	BCF   0x4F,needToUpdate,0
			;			}
			;
			;         getTemp();
m021	RCALL getTemp
			;         putchar( PORTA );
	MOVF  PORTA,W,0
	RCALL putchar
			;         putchar( filteredInputs );
	MOVF  filteredInputs,W,0
	RCALL putchar
			;         putchar( patternSelect );
	MOVF  patternSelect,W,0
	RCALL putchar
			;			putchar( temperature );
	MOVF  temperature,W,0
	RCALL putchar
			;
			;      }
			;   }
	BRA   m019
_const1
	MOVWF ci,0
	MOVF  ci,W,0
	ADDLW 54
	MOVWF TBLPTR,0
	MOVLW 4
	CLRF  TBLPTR+1,0
	ADDWFC TBLPTR+1,1,0
	CLRF  TBLPTR+2,0
	TBLRD *
	MOVF  TABLAT,W,0
	RETURN
	DW    0x7000
	DW    0x8781
	DW    0xBFA9
	DW    0xD6
	DW    0x6F60
	DW    0x9274
	DW    0xBBA6
	DW    0x4600
	DW    0x5753
	DW    0x8170
	DW    0x92
	DW    0x241C
	DW    0x3827
	DW    0x4F43
	DW    0x4779
	DW    0x348C
	DW    0x17A9
	DW    0x74EC

	END


; *** KEY INFO ***

; 0x00006E    6 word(s)  0 % : time_config
; 0x00007A   11 word(s)  0 % : isr_time
; 0x000136    4 word(s)  0 % : initDebounce
; 0x00013E   20 word(s)  0 % : debounce
; 0x000090    4 word(s)  0 % : pwm2_config
; 0x0000B4   12 word(s)  0 % : isr_pwm2
; 0x000098    6 word(s)  0 % : pwm2_set
; 0x0000A4    3 word(s)  0 % : pwm2_stop
; 0x0000AA    5 word(s)  0 % : pwm2_start
; 0x0000CC   17 word(s)  0 % : io_config
; 0x0000EE   18 word(s)  0 % : putchar
; 0x000112   17 word(s)  0 % : isr_putchar
; 0x000134    1 word(s)  0 % : isr_getchar
; 0x00018E    7 word(s)  0 % : chk_generate
; 0x00019C    7 word(s)  0 % : chk_compare
; 0x0001BA   26 word(s)  0 % : ee_putchar
; 0x0001AA    8 word(s)  0 % : ee_getchar
; 0x000202   27 word(s)  0 % : ee_writeByte
; 0x0001F4    7 word(s)  0 % : isr_ee_write
; 0x000238   10 word(s)  0 % : epwm_config
; 0x00024C   17 word(s)  0 % : epwm_set
; 0x00026E    6 word(s)  0 % : irda_config
; 0x00027A   11 word(s)  0 % : isr_irda
; 0x000008    2 word(s)  0 % : highPriorityServer
; 0x000018   29 word(s)  0 % : lowPriorityServer
; 0x000052   14 word(s)  0 % : configAtoD
; 0x000166   20 word(s)  0 % : chk_sum
; 0x0001EE    3 word(s)  0 % : ee_writeEmpty
; 0x000290    6 word(s)  0 % : getTemp
; 0x00029C    8 word(s)  0 % : updateTempRange
; 0x0002AC   11 word(s)  0 % : setTempRange
; 0x0002C2   93 word(s)  1 % : setPattern
; 0x000420   29 word(s)  0 % : _const1
; 0x00037C    4 word(s)  0 % : configTimer0
; 0x000384   78 word(s)  0 % : main

; RAM usage: 80 bytes (9 local), 432 bytes free
; Maximum call level: 2 (+2 for interrupt)
; Total of 549 code words (6 %)
